package com.ly.aidlpratice.handwritten

import android.os.IBinder
import android.os.Parcel
import android.os.RemoteException
import com.ly.aidlpratice.bean.Book

class ClientBookProxy(private val mServerBinder: IBinder) : IBookInterface {

    @Throws(RemoteException::class)
    override fun getBook(): Book {
        val data = Parcel.obtain()
        val reply = Parcel.obtain()
        try {
            data.writeInterfaceToken(BOOK_INTERFACE_TOKEN)
            mServerBinder.transact(TRANSACTION_GET_BOOK, data, reply, 0)
            val status = reply.readInt()
            return if (status != 0)
                Book.CREATOR.createFromParcel(reply)
            else
                Book("", -1, -1f)
        } finally {
            data.recycle()
            reply.recycle()
        }
    }

    @Throws(RemoteException::class)
    override fun getAllBook(): List<Book> {
        val data = Parcel.obtain()
        val reply = Parcel.obtain()
        try {
            data.writeInterfaceToken(BOOK_INTERFACE_TOKEN)
            mServerBinder.transact(TRANSACTION_GET_ALL_BOOK, data, reply, 0)
            val result = reply.createTypedArrayList(Book.CREATOR)
            return result ?: emptyList()
        } finally {
            data.recycle()
            reply.recycle()
        }
    }

    @Throws(RemoteException::class)
    override fun isContainBook(name: String): Boolean {
        val data = Parcel.obtain()
        val reply = Parcel.obtain()
        try {
            data.writeInterfaceToken(BOOK_INTERFACE_TOKEN)
            data.writeString(name)
            mServerBinder.transact(TRANSACTION_IS_CONTAIN_BOOK, data, reply, 0)
            return reply.readInt() != 0
        } finally {
            data.recycle()
            reply.recycle()
        }
    }

    @Throws(RemoteException::class)
    override fun updateBookPrice(code: Int, price: Float) {
        val data = Parcel.obtain()
        try {
            data.writeInterfaceToken(BOOK_INTERFACE_TOKEN)
            data.writeInt(code)
            data.writeFloat(price)
            mServerBinder.transact(TRANSACTION_UPDATE_BOOK_PRICE, data, null, 0)
        } finally {
            data.recycle()
        }
    }

    @Throws(RemoteException::class)
    override fun getBookPrice(code: Int): Float {
        val data = Parcel.obtain()
        val reply = Parcel.obtain()
        try {
            data.writeInterfaceToken(BOOK_INTERFACE_TOKEN)
            data.writeInt(code)
            mServerBinder.transact(TRANSACTION_GET_BOOK_PRICE, data, reply, 0)
            return reply.readFloat()
        } finally {
            data.recycle()
            reply.recycle()
        }
    }

    @Throws(RemoteException::class)
    override fun insertBook(book: Book) {
        val data = Parcel.obtain()
        try {
            data.writeInterfaceToken(BOOK_INTERFACE_TOKEN)
            book.writeToParcel(data, 0)
            mServerBinder.transact(TRANSACTION_INSERT_BOOK, data, null, 0)
        } finally {
            data.recycle()
        }
    }

    @Throws(RemoteException::class)
    override fun insertBookList(list: List<Book>) {
        val data = Parcel.obtain()
        try {
            data.writeInterfaceToken(BOOK_INTERFACE_TOKEN)
            data.writeTypedList(list)
            mServerBinder.transact(TRANSACTION_INSERT_BOOK_LIST, data, null, 0)
        } finally {
            data.recycle()
        }
    }

    @Throws(RemoteException::class)
    override fun getBookMap(): Map<*, *> {
        val data = Parcel.obtain()
        val reply = Parcel.obtain()
        try {
            data.writeInterfaceToken(BOOK_INTERFACE_TOKEN)
            mServerBinder.transact(TRANSACTION_GET_BOOK_MAP, data, reply, 0)
            val status = reply.readInt()
            return if (status != 0)
                reply.readHashMap(javaClass.classLoader) ?: emptyMap<Any, Any>()
            else
                emptyMap<Any, Any>()
        } finally {
            data.recycle()
            reply.recycle()
        }
    }

    @Throws(RemoteException::class)
    override fun insertBookMap(map: Map<*, *>) {
        val data = Parcel.obtain()
        try {
            data.writeInterfaceToken(BOOK_INTERFACE_TOKEN)
            data.writeMap(map)
            mServerBinder.transact(TRANSACTION_INSERT_BOOK_MAP, data, null, 0)
        } finally {
            data.recycle()
        }
    }

    @Throws(RemoteException::class)
    override fun registerCallback(callback: IBookCallback) {
        val data = Parcel.obtain()
        try {
            data.writeInterfaceToken(BOOK_INTERFACE_TOKEN)
            data.writeStrongBinder(callback.asBinder())
            mServerBinder.transact(TRANSACTION_REGISTER_CALLBACK, data, null, 0)
        } finally {
            data.recycle()
        }
    }

    @Throws(RemoteException::class)
    override fun unregisterCallback(callback: IBookCallback) {
        val data = Parcel.obtain()
        try {
            data.writeInterfaceToken(BOOK_INTERFACE_TOKEN)
            data.writeStrongBinder(callback.asBinder())
            mServerBinder.transact(TRANSACTION_UNREGISTER_CALLBACK, data, null, 0)
        } finally {
            data.recycle()
        }
    }

    override fun asBinder(): IBinder {
        return mServerBinder
    }
}